package com.etl.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etl.entity.*;
import com.etl.mapper.*;
import com.etl.service.IEtlLogService;
import com.etl.webSocket.WebSocketUser;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2019/10/21.
 */
@Service
@Slf4j
public class EtlLogServiceImpl implements IEtlLogService {


    @Resource
    private EtlTaskLogMapper etlTaskLogMapper;

    private static Pattern dateRex = Pattern.compile("\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}");


    /**
     * 【接口】查询某任务执行历史
     *
     * @param kid
     * @param pages
     * @param sizes
     */
    @Override
    public PageInfo<EtlTaskLog> history(Integer pages, Integer sizes, Long kid, String logType) {
        PageHelper.startPage(pages, sizes);
        QueryWrapper<EtlTaskLog> hxWrapper = new QueryWrapper<>();
        hxWrapper.eq("kid", kid);
        hxWrapper.eq("log_type", logType);
        hxWrapper.orderByDesc("create_date");
        List<EtlTaskLog> etlTaskLogs = etlTaskLogMapper.selectList(hxWrapper);
        PageInfo<EtlTaskLog> pageInfoDemo = new PageInfo<>(etlTaskLogs);
        return pageInfoDemo;
    }

    /**
     * 查询某次执行日志详情
     *
     * @param logId
     * @return
     */
    @Override
    public String historyDetail(Long logId) {
        QueryWrapper<EtlTaskLog> hxWrapper = new QueryWrapper<>();
        hxWrapper.eq("log_id", logId);
        hxWrapper.orderByDesc("create_date");
        EtlTaskLog etlTaskLog = etlTaskLogMapper.selectOne(hxWrapper);
        StringBuffer sb = new StringBuffer();
        if (etlTaskLog != null) {
            String logDetail = etlTaskLogMapper.getLogDetailByBatchId(etlTaskLog.getBatchId());
            if (Strings.isNotBlank(logDetail)) {
                logDetail = logDetail.replace("\n", "</br>")
                        .replaceAll("ERROR", "<span style='color: #ed4014;'>ERROR</span>")
                        .replaceAll("Error", "<span style='color: #ed4014;'>Error</span>")
                        .replaceAll("error", "<span style='color: #ed4014;'>error</span>")
                        .replaceAll("LOCAL_DB", "【BI数据源】");
                Matcher m = dateRex.matcher(logDetail);
                while (m.find()) {
                    String b = "<span style='color: #2d8cf0;'>" + m.group() + "</span>";
                    m.appendReplacement(sb, b);
                }
                m.appendTail(sb);
            }
            return sb.toString();
        }
        return null;
    }



    @Async
    @Override
    public void readLogWebSocket(WebSocketUser webSocketUser) {
        log.info("LoggingWebSocketServer 任务开始");
        boolean first = true;
        //日志文件路径，获取最新的
        String filePath = System.getProperty("user.home") + "/etlTaskLog/etl_task.log";
        //清空文件
        File logFile = null;
        try {
            logFile = new File(filePath);
            FileWriter fileWriter = new FileWriter(logFile);
            fileWriter.write("");
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        while (webSocketUser.getIsTaskRunning()) {
            BufferedReader reader = null;
            try {
                //字符流
                reader = new BufferedReader(new FileReader(logFile));
                Object[] lines = reader.lines().toArray();

                //只取从上次之后产生的日志
                Object[] copyOfRange = Arrays.copyOfRange(lines, webSocketUser.getLogLength(), lines.length);

                //对日志进行着色，更加美观  PS：注意，这里要根据日志生成规则来操作
                for (int i = 0; i < copyOfRange.length; i++) {
                    String line = (String) copyOfRange[i];
                    //处理等级
                    line = line.replace("DEBUG", "<span style='color: #2d8cf0;'>DEBUG</span>")
                            .replace("INFO", "<span style='color: #2db7f5;'>INFO</span>")
                            .replace("WARN", "<span style='color: #ff9900;'>WARN</span>")
                            .replace("ERROR", "<span style='color: #ed4014;'>ERROR</span>");
                    copyOfRange[i] = line;
                }
                //存储最新一行开始
                webSocketUser.setLogLength(lines.length);
                //第一次如果太大，截取最新的200行就够了，避免传输的数据太大
                if (first && copyOfRange.length > 200) {
                    copyOfRange = Arrays.copyOfRange(copyOfRange, copyOfRange.length - 200, copyOfRange.length);
                    first = false;
                }
                String result = StringUtils.join(copyOfRange, "<br/>");

                //发送
                if (Strings.isNotBlank(result)) {
                    try {
                        webSocketUser.getSession().getBasicRemote().sendText(result);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //休眠一秒
                Thread.sleep(1000);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                log.error(e.getMessage());
                webSocketUser.setIsTaskRunning(false);
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException ignored) {
                    ignored.printStackTrace();
                }
            } catch (Exception e) {
                //捕获但不处理
                e.printStackTrace();
                log.error(e.getMessage());
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException ignored) {
                    ignored.printStackTrace();
                }
            }
        }
        log.info("LoggingWebSocketServer 任务结束");
    }




}

